package com.tailyou.hms.firstapp.act;

import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.tailyou.hms.firstapp.R;

import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class HttpUrlConnectionActivity extends AppCompatActivity {

    private TextView tvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_http_url_connection);
        tvContent = findViewById(R.id.tvContent);
        findViewById(R.id.btnPost).setOnClickListener(v -> doPost("https://www.wanandroid.com/user/login"));
        findViewById(R.id.btnGet).setOnClickListener(v -> doGet("https://www.wanandroid.com/article/list/0/json"));
        findViewById(R.id.btnDownload).setOnClickListener(v -> doDownload("https://api.worldskills.org/resources/download/12481/14919/15847?l=en"));
    }

    /**
     * GET请求
     *
     * @param url
     */
    private void doGet(String url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 获取连接、设置参数
                    URL httpUrl = new URL(url);
                    URLConnection urlConnection = httpUrl.openConnection();
                    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
                    // 设置连接超时时间, 值必须大于0，设置为0表示不超时 单位为“毫秒”
                    httpURLConnection.setConnectTimeout(30000);
                    // 设置读超时时间, 值必须大于0，设置为0表示不超时 单位毫秒
                    httpURLConnection.setReadTimeout(60000);
                    // 设置为 GET 请求,
                    httpURLConnection.setRequestMethod("GET");
                    // 设置请求类型为 application/json
                    httpURLConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                    // 设置可接受的数据类型
                    httpURLConnection.setRequestProperty("Accept", "*/*");
                    // 设置保持长链接
                    httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
                    // 设置自定义头 Token
                    httpURLConnection.setRequestProperty("Token", "123456");
                    // 设置不使用缓存， 默认为 true 使用缓存
                    httpURLConnection.setUseCaches(false);
                    // 设置是否进行重定向，注意此处为 静态方法，表示所有的请求都不支持重定向，默认为true
                    HttpURLConnection.setFollowRedirects(false);
                    // 设置单次请求是否支持重定向，默认为 setFollowRedirects 方法设置的值
                    httpURLConnection.setInstanceFollowRedirects(false);
                    // 建立连接
                    httpURLConnection.connect();

                    // 获取响应数据-响应头
                    Map<String, List<String>> headerFields = httpURLConnection.getHeaderFields();

                    // 获取响应数据-状态
                    int responseCode = httpURLConnection.getResponseCode();
                    // 获取响应数据-描述
                    String msg = httpURLConnection.getResponseMessage();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        // 获取响应数据-数据
                        InputStream inputStream = httpURLConnection.getInputStream();
                        // 定义一个临时字节输出流
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        try {
                            // 开始读取数据
                            byte[] buffer = new byte[256];
                            int len = 0;
                            while ((len = inputStream.read(buffer)) > 0) {
                                baos.write(buffer, 0, len);
                            }
                            String repContent = new String(baos.toByteArray(), StandardCharsets.UTF_8);
                            runOnUiThread(() -> tvContent.setText(repContent));
                        } finally {
                            // 关闭输入、输出流
                            inputStream.close();
                            baos.close();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * POST请求
     *
     * @param url
     */
    private void doPost(String url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 获取连接、设置参数
                    URL httpUrl = new URL(url);
                    URLConnection urlConnection = httpUrl.openConnection();
                    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
                    // 设置连接超时时间, 值必须大于0，设置为0表示不超时 单位为“毫秒”
                    httpURLConnection.setConnectTimeout(30000);
                    // 设置读超时时间, 值必须大于0，设置为0表示不超时 单位毫秒
                    httpURLConnection.setReadTimeout(60000);
                    // 设置为 POST 请求,
                    httpURLConnection.setRequestMethod("POST");
                    // 设置请求类型为 application/x-www-form-urlencoded
                    httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    // 设置可接受的数据类型
                    httpURLConnection.setRequestProperty("Accept", "*/*");
                    // 设置保持长链接
                    httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
                    // 设置自定义头 Token
                    httpURLConnection.setRequestProperty("Token", "123456");
                    // 设置不使用缓存， 默认为 true 使用缓存
                    httpURLConnection.setUseCaches(false);
                    // 设置是否进行重定向，注意此处为 静态方法，表示所有的请求都不支持重定向，默认为true
                    HttpURLConnection.setFollowRedirects(false);
                    // 设置单次请求是否支持重定向，默认为 setFollowRedirects 方法设置的值
                    httpURLConnection.setInstanceFollowRedirects(false);

                    //指示应用程序要将数据写入URL连接,其值默认为false（是否传参）
                    httpURLConnection.setDoOutput(true);
                    String params = "username=" + URLEncoder.encode("tailyou04", "utf-8") + "&password=" + URLEncoder.encode("tailyou02", "utf-8");
                    //传入参数
                    OutputStream out = httpURLConnection.getOutputStream();
                    out.write(params.getBytes());
                    out.flush(); //清空缓冲区,发送数据
                    out.close();

                    // 获取响应数据-响应头
                    Map<String, List<String>> headerFields = httpURLConnection.getHeaderFields();
                    // 获取响应数据-状态
                    int responseCode = httpURLConnection.getResponseCode();
                    // 获取响应数据-描述
                    String msg = httpURLConnection.getResponseMessage();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        // 获取响应数据-数据
                        InputStream inputStream = httpURLConnection.getInputStream();
                        // 定义一个临时字节输出流
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        try {
                            // 开始读取数据
                            byte[] buffer = new byte[256];
                            int len = 0;
                            while ((len = inputStream.read(buffer)) > 0) {
                                baos.write(buffer, 0, len);
                            }
                            String repContent = new String(baos.toByteArray(), StandardCharsets.UTF_8);
                            runOnUiThread(() -> tvContent.setText(repContent));
                        } finally {
                            // 关闭输入、输出流
                            inputStream.close();
                            baos.close();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 文件下载
     *
     * @param url
     */
    private void doDownload(String url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL httpUrl = new URL(url);
                    URLConnection urlConnection = httpUrl.openConnection();
                    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
                    InputStream inputStream = httpURLConnection.getInputStream();
                    File externalFilesDir = ContextCompat.getExternalFilesDirs(HttpUrlConnectionActivity.this, Environment.DIRECTORY_DOWNLOADS)[0];
                    File file = new File(externalFilesDir, System.currentTimeMillis() + ".pdf");
                    OutputStream outputStream = new FileOutputStream(file);
                    byte[] bytes = new byte[1024];
                    int length;
                    while ((length = inputStream.read(bytes)) != -1) {
                        outputStream.write(bytes, 0, length);
                    }
                    runOnUiThread(() -> tvContent.setText("下载完成"));
                    inputStream.close();
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 上传文件
     *
     * @param file
     * @param url
     */
    private void doUpload(File file, String url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String CHARSET = "utf-8"; //设置编码
                String BOUNDARY = UUID.randomUUID().toString();  //边界标识   随机生成
                String PREFIX = "--", LINE_END = "\r\n";
                String CONTENT_TYPE = "multipart/form-data";   //内容类型
                try {
                    URL httpUrl = new URL(url);
                    URLConnection urlConnection = httpUrl.openConnection();
                    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
                    // 设置连接超时时间, 值必须大于0，设置为0表示不超时 单位为“毫秒”
                    httpURLConnection.setConnectTimeout(30000);
                    // 设置读超时时间, 值必须大于0，设置为0表示不超时 单位毫秒
                    httpURLConnection.setReadTimeout(60000);
                    // 设置为 POST 请求,
                    httpURLConnection.setRequestMethod("POST");
                    httpURLConnection.setDoInput(true);  //允许输入流
                    httpURLConnection.setDoOutput(true); //允许输出流
                    httpURLConnection.setUseCaches(false);  //不允许使用缓存
                    httpURLConnection.setRequestMethod("POST");  //请求方式
                    httpURLConnection.setRequestProperty("Charset", CHARSET);  //设置编码
                    httpURLConnection.setRequestProperty("connection", "keep-alive");
                    httpURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
                    if (file != null) {
                        OutputStream outputSteam = httpURLConnection.getOutputStream();
                        DataOutputStream dos = new DataOutputStream(outputSteam);
                        StringBuffer sb = new StringBuffer();
                        sb.append(PREFIX);
                        sb.append(BOUNDARY);
                        sb.append(LINE_END);
                        sb.append("Content-Disposition: form-data; name=\"img\"; filename=\"" + file.getName() + "\"" + LINE_END);
                        sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
                        sb.append(LINE_END);
                        dos.write(sb.toString().getBytes());
                        InputStream is = new FileInputStream(file);
                        byte[] bytes = new byte[1024];
                        int len;
                        while ((len = is.read(bytes)) != -1) {
                            dos.write(bytes, 0, len);
                        }
                        is.close();
                        dos.write(LINE_END.getBytes());
                        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
                        dos.write(end_data);
                        dos.flush();
                        int res = httpURLConnection.getResponseCode();
                        if (res == 200) {
                            runOnUiThread(() -> tvContent.setText("上传成功"));
                        }
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}